package com.rtsapp.server.gamelog.server.service.impl;

import com.rtsapp.server.domain.EntityBuilder;
import com.rtsapp.server.gamelog.api.GamelogType;
import com.rtsapp.server.gamelog.cmd.cmd.Commands;
import com.rtsapp.server.gamelog.cmd.cmd.LoginRequest;
import com.rtsapp.server.gamelog.cmd.cmd.SendLogRequest;
import com.rtsapp.server.gamelog.cmd.cmd.StartLogCollectResponse;
import com.rtsapp.server.gamelog.cmd.model.*;
import com.rtsapp.server.gamelog.server.dao.GamelogDao;
import com.rtsapp.server.gamelog.server.dao.impl.ConfigDao;
import com.rtsapp.server.gamelog.server.entity.ConfigEntity;
import com.rtsapp.server.gamelog.server.handler.Constants;
import com.rtsapp.server.gamelog.server.service.ILogService;
import com.rtsapp.server.logger.Logger;
import com.rtsapp.server.logger.LoggerFactory;
import com.rtsapp.server.network.protocol.command.ICommand;
import com.rtsapp.server.network.session.Session;
import com.rtsapp.server.utils.time.DayPeriodCalendar;

/**
 * Created by admin on 16-7-19.
 */
public class LogServiceImpl implements ILogService {

    private static final Logger LOG = LoggerFactory.getLogger( LogServiceImpl.class );

    private static final int CONFIG_ID = 1;

    private final GamelogDao gamelogDao;
    private final ConfigDao configDao;
    private final ConfigEntity config;


    public LogServiceImpl(ConfigDao configDao, GamelogDao gamelogDao) {
        this.configDao = configDao;
        this.gamelogDao = gamelogDao;

        //加载配置
        ConfigEntity configEntiy =   this.configDao.get( CONFIG_ID  );
        if( configEntiy == null ){
            configEntiy = EntityBuilder.newEntity( ConfigEntity.class );
            configEntiy.setId(CONFIG_ID);

            long logStartMils =  new DayPeriodCalendar(0).getPeriodStartMils( System.currentTimeMillis() );

            configEntiy.setLogStartMils( logStartMils );
            this.configDao.insert(configEntiy);
        }
        config = configEntiy;

    }




    @Override
    public ConfigEntity getConfig(){
        return this.config;
    }

    @Override
    public void updateConfig( ConfigEntity entity ){
        this.configDao.update( entity );
    }


    @Override
    public void execute(  Session session, int commandId, ICommand request ) {

        switch (commandId) {
            case Commands.Login:
                login(session, request );
                break;
            case Commands.SendLog:
                sendLog(  session, request );
                break;

        }

    }

    private void login( Session session, ICommand request ){

        //如果已经登录，再次受到登录消息，表示错误
        if( session.getAttribute( Constants.ATTR_LOGIN_CLIENT ) != null ){
            session.close();
            LOG.error( "重复登录, 关闭连接" );
            return;
        }


        LoginRequest loginRequest = (LoginRequest)request;
        ClientInfo clientInfo =  loginRequest.getClientInfo();
        session.setAttribute( Constants.ATTR_LOGIN_CLIENT, clientInfo );


        //发送开始采集的消息
        startLogCollect( session , clientInfo );
    }


    private void sendLog( Session session,  ICommand req ){

        SendLogRequest request = (SendLogRequest)req;
        for( int i = 0; i <  request.getLogList().size(); i++){
            LogInfo logInfo =  request.getLogList().get( i );

            saveLog(logInfo.getLogType(), logInfo.getLog());
        }
    }

    private void saveLog( String logType, String log ){
        gamelogDao.insertLog(logType, log);
    }


    //开始采集日志
    private void startLogCollect(Session session,  ClientInfo clientInfo ){
        StartLogCollectResponse startResponse = new StartLogCollectResponse();

        GamelogType[] types =  GamelogType.values();

        for(ServerInfo serverInfo  : clientInfo.getServerList() ) {

            ServerLogProgress servLogProgress = new ServerLogProgress();
            servLogProgress.setServerInfo(serverInfo);
            startResponse.getLogProgressList().add(servLogProgress);

            for (GamelogType type : types) {
                //1. 查询数据库, 取得每一个日志类型, 最大的时间, 以及那一天总共有多少条日志
                long maxLogMils = gamelogDao.queryMaxLogTimeMils(type.getTableName(), serverInfo.getGameId(), serverInfo.getAreaId(), serverInfo.getServerId());

                //2. 日志数量
                int logSize = gamelogDao.queryLogCountInDay(type.getTableName(), maxLogMils, serverInfo.getGameId(), serverInfo.getAreaId(), serverInfo.getServerId());

                if( maxLogMils < config.getLogStartMils() ){
                    maxLogMils = config.getLogStartMils();
                    logSize = 0;
                }

                LogProgress progress = new LogProgress();
                progress.setLogType(type.getName());
                progress.setStopLogDay(maxLogMils);
                progress.setStopLogLine(logSize);

                servLogProgress.getProgressList().add( progress );
            }
        }

        session.write( startResponse );
    }

}
